"""
使用方法:
1) 第一次运行：会打开 Edge，手动登录淘宝，脚本会保存 cookies 到 taobao_cookies.json
2) 之后可调用 load_and_add_cookies() 来注入已保存的 cookie（示例在 main 中注释）
"""

import time
import json
import os
from typing import List, Dict, Optional

from selenium import webdriver

# 设置浏览器驱动msedgedriver.exe
WEBDRIVER_PATH = r"H:\chromedriver64\msedgedriver.exe"
COOKIES_FILE = "taobao_cookies.json"
TAOBAO_URL = "https://www.taobao.com/"

def create_edge_driver(webdriver_path: Optional[str] = None, headless: bool = False):

    # 导入 Edge 专用类
    options = None
    try:
        from selenium.webdriver.edge.options import Options as EdgeOptions
        options = EdgeOptions()
        # edge 基于 chromium
        try:
            options.use_chromium = True
        except Exception:
            pass
        # 安全地添加参数有些 selenium 版本的 Options 没有 add_argument
        if hasattr(options, "add_argument"):
            if headless:
                try:
                    options.add_argument("--headless=new")
                except Exception:
                    options.add_argument("--headless")
                options.add_argument("--window-size=1920,1080")
            # start-maximized 若不支持也不会抛出致命错误（有些版本会忽略）
            try:
                options.add_argument("--start-maximized")
            except Exception:
                pass
    except Exception:
        options = None  # 不能构建 options 就 fallback

    # 优先尝试新版构造（service, options），若失败再回退到旧构造（executable_path）
    # 注意：某些旧 selenium 的 webdriver.Edge() 不支持 service 参数，会抛 TypeError
    try:
        # 新版 selenium: 使用 Service
        from selenium.webdriver.edge.service import Service as EdgeService
        service = None
        if webdriver_path:
            service = EdgeService(executable_path=webdriver_path)
        else:
            service = EdgeService()  # 可能会失败，如果系统 PATH 没有 driver
        # 尝试使用 service + options（如果 options 为 None 也可以传）
        try:
            if options is not None:
                driver = webdriver.Edge(service=service, options=options)
            else:
                driver = webdriver.Edge(service=service)
        except TypeError:
            # 有些环境不支持 service 参数，再尝试用 executable_path 方式（新 options 若支持也传）
            if webdriver_path:
                if options is not None:
                    driver = webdriver.Edge(executable_path=webdriver_path, options=options)
                else:
                    driver = webdriver.Edge(executable_path=webdriver_path)
            else:
                # 最后兜底：直接调用不带路径（依赖 PATH）
                if options is not None:
                    driver = webdriver.Edge(options=options)
                else:
                    driver = webdriver.Edge()
    except Exception as e_new:
        # 若以上都失败，再尝试最简单的可用初始化（仅 executable_path）
        try:
            if webdriver_path:
                driver = webdriver.Edge(executable_path=webdriver_path)
            else:
                driver = webdriver.Edge()
        except Exception as e_fallback:
            # 所有尝试都失败，抛出更详细的信息
            raise RuntimeError(
                "无法启动 Edge webdriver。请检查 selenium 版本、msedgedriver 路径和驱动是否与浏览器匹配。\n"
                f"新接口尝试错误: {e_new}\n回退尝试错误: {e_fallback}"
            )

    # 基本设置
    try:
        driver.maximize_window()
    except Exception:
        pass
    try:
        driver.implicitly_wait(10)
    except Exception:
        pass

    return driver

def save_cookies_after_manual_login(driver, cookies_file: str = COOKIES_FILE, wait_seconds: int = 300):
    driver.get(TAOBAO_URL)
    print(f"请在打开的 Edge 浏览器中完成淘宝登录（扫码/账号密码/等），脚本会等待 {wait_seconds} 秒。")
    time.sleep(wait_seconds)

    try:
        cookies = driver.get_cookies()
        if not cookies:
            print("没有获取到 Cookie，可能登录未完成或页面未加载。")
        else:
            print(f"获取到 {len(cookies)} 条 Cookie，正在保存到文件：{cookies_file}")
            with open(cookies_file, "w", encoding="utf-8") as f:
                json.dump(cookies, f, ensure_ascii=False, indent=2)
            print("保存完成。")
    except Exception as e:
        print("获取或保存 Cookie 时发生异常：", e)

def load_cookies_from_file(cookies_file: str = COOKIES_FILE) -> List[Dict]:
    if not os.path.exists(cookies_file):
        raise FileNotFoundError(f"Cookie 文件不存在：{cookies_file}")
    with open(cookies_file, "r", encoding="utf-8") as f:
        cookies = json.load(f)
    return cookies

def add_cookies_to_driver(driver, cookies: List[Dict]):
    """
    注入 cookie，注意：
     - 必须先打开目标域名（已在调用处处理）
     - 对单个 cookie 做兼容清理（expiry 类型、domain 缺失等）
    """
    for cookie in cookies:
        c = cookie.copy()
        # Selenium add_cookie 接受的字段：name, value, path, domain, secure, httpOnly, expiry, sameSite
        allowed = {"name", "value", "path", "domain", "secure", "httpOnly", "expiry", "sameSite"}
        c = {k: v for k, v in c.items() if k in allowed}
        # 如果没有 domain，强制设置为主站域
        if "domain" not in c or not c.get("domain"):
            c["domain"] = ".taobao.com"
        # expiry 必须为 int（若存在）
        if "expiry" in c:
            try:
                c["expiry"] = int(c["expiry"])
            except Exception:
                c.pop("expiry", None)
        try:
            driver.add_cookie(c)
        except Exception as e:
            # 捕获单条 cookie 注入异常并继续
            print(f"注入 cookie {c.get('name')} 时出错：{e}")

def load_and_apply_cookies(driver, cookies_file: str = COOKIES_FILE):
    """
    读取 cookies 文件并注入到打开的 driver，然后刷新页面以生效。
    """
    cookies = load_cookies_from_file(cookies_file)
    # 先打开域名，才能 add_cookie
    driver.get(TAOBAO_URL)
    time.sleep(1)
    add_cookies_to_driver(driver, cookies)
    time.sleep(0.5)
    driver.refresh()
    time.sleep(2)
    print("已注入 cookies 并刷新页面，请检查是否已登录。")

def main():
    # 1) 启动 Edge（自动兼容不同 selenium）
    driver = create_edge_driver(WEBDRIVER_PATH, headless=False)

    try:
        # === 情况 A：第一次运行 -> 手动登录并保存 cookie ===
        save_cookies_after_manual_login(driver, COOKIES_FILE, wait_seconds=300)

        # === 情况 B：后续运行 -> 注入已保存 cookie（取消注释以使用） ===
        # 注意：注入 cookie 要重新创建 driver 或在保存 cookie 后继续使用同一个 driver。
        # 如果你希望注入后马上查看效果，可以在保存 cookies 后注释掉 driver.quit()，然后调用下面：
        # load_and_apply_cookies(driver, COOKIES_FILE)

    finally:
        # 等一点让你看到页面（可按需调整或注释）
        time.sleep(3)
        try:
            driver.quit()
        except Exception:
            pass

if __name__ == "__main__":
    main()
